﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Telerik.WinControls;
using Telerik.WinControls.UI;
using System.IO;
using Aspose.Cells;

namespace UnigenReport.Form
{
    public partial class ucShippingRequest : UserControl
    {
        public bool isCallFromInvoice = false;
        public int shipToId = 0;
        public List<ShippingRequest> refData = new List<ShippingRequest>();
        private UnigenDataContext db;

        #region Thiết lập

        public ucShippingRequest()
        {
            InitializeComponent();
            //Phân quyền
            if (Variables.UserRoleID == 0)
                btnDelete.Visibility = ElementVisibility.Collapsed;
            if(Variables.UserRoleID < 2)
                btnApprove.Visibility = ElementVisibility.Collapsed;


            SetEvent();
            Common.SetMenuShortcut(btnInsert, btnUpdate, btnDelete, btnGetData, btnCloseForm);
            cboStatus.SelectedIndex = 1;
            cboActive.SelectedIndex = 0;
            cboListSize.SelectedIndex = 0;
        }

        public ucShippingRequest Select(List<ShippingRequest> list)
        {
            isCallFromInvoice = true;
            refData = list;
            return this;
        }

        /// <summary>
        /// Khai báo các sự kiện
        /// </summary>
        private void SetEvent()
        {
            this.Load += OnLoad;
            this.btnInsert.Click += new System.EventHandler(this.btnInsert_Click);
            this.btnUpdate.Click += new System.EventHandler(this.btnUpdate_Click);
            this.btnDelete.Click += new System.EventHandler(this.btnDelete_Click);
            this.btnGetData.Click += new System.EventHandler(this.btnGetData_Click);
            this.btnApprove.Click += new System.EventHandler(this.btnApprove_Click);
            this.btnCloseForm.Click += new System.EventHandler(this.btnCloseForm_Click);
            this.btnSearch.Click += new System.EventHandler(this.btnSearch_Click);

            this.btnSave.Click += new System.EventHandler(this.btnSave_Click);

            this.btnExport.Click += new System.EventHandler(this.btnExport_Click);
            this.btnPrint.Click += new System.EventHandler(this.btnPrint_Click);

            this.btnImport.Click += new System.EventHandler(this.btnImport_Click);
            this.btnExportTemp.Click += new System.EventHandler(this.btnExportTemp_Click);
            this.btnSaveImport.Click += new System.EventHandler(this.btnSaveImport_Click);
            this.btnCancelImport.Click += new System.EventHandler(this.btnCancelImport_Click);

            this.grvShippingRequest.CellClick += grvShippingRequest_CellClick;
            this.grvShippingRequest.CellDoubleClick += grvShippingRequest_CellDoubleClick;
            this.chkCreated.ToggleStateChanged += new StateChangedEventHandler(chkCreated_ToggleStateChanged);
        }

        /// <summary>
        /// Hàm load form
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnLoad(object sender, EventArgs e)
        {
            //Load default
            SetDefault();
            txtCreated.Value = DateTime.Now;
        }

        /// <summary>
        /// Thiết lập các giá trị mặc định của form
        /// </summary>
        private void SetDefault()
        {
            //Source type
            var dtbStatus = new DataTable();
            dtbStatus.Columns.Add("Id");
            dtbStatus.Columns.Add("Name");
            dtbStatus.Rows.Add(0, "---");
            dtbStatus.Rows.Add(1, "CLOSE");

            sourceStatus.DataSource = dtbStatus;

            //Bind dữ liệu chính
            BindData();
        }

        /// <summary>
        /// Lấy dữ liệu chính
        /// </summary>
        private void BindData()
        {
            try
            {
                //Data bind
                var size = Convert.ToInt32(cboListSize.Text);
                sourceShippingRequest.DataSource = GetData(size);
                
                //Interface
                if (isCallFromInvoice)
                {
                    btnApprove.Visibility = btnImport.Visibility = btnExportTemp.Visibility = ElementVisibility.Collapsed;
                    grvShippingRequest.Columns["Selected"].IsVisible = true;
                    cboStatus.Enabled = cboActive.Enabled = false;
                    btnSave.Visibility = ElementVisibility.Visible;
                }
                //STT
                Common.SetNo(grvShippingRequest);
            }
            catch (Exception ex)
            {
                Common.ShowErrorMess("BindData - " + ex.Message);
            }
        }

        private List<ShippingRequest> GetData(int size = 65000)
        {
            db = new UnigenDataContext();
            var wo = txtWO.Text.Trim().Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList();
            var date = Convert.ToDateTime(txtCreated.Value.ToString("yyyy-MM-dd 00:00:00"));

            return db.ShippingRequests.Where(p =>
                (cboActive.SelectedIndex == 1 ? p.Active == true : (cboActive.SelectedIndex == 2 ? p.Active == false : 1 == 1))// Theo active
                && (wo.Count > 0 ? wo.Contains(p.WorldOrder.WO) : 1 == 1) //Nếu có lọc theo wo thì so sánh
                && (chkCreated.Checked ? p.CreatedDate > date : 1 == 1) //Nếu tìm theo điều kiên created date
                    //Nếu lấy từ form invoice thì phải là trạng thái chưa xử lý, đã xn, ko nằm trong list có sẵn và lấy theo shipAddress
                && (isCallFromInvoice ? (p.Active == true && p.Status == 0 && !refData.Contains(p) && p.ShipAddressId == shipToId) : 1 == 1)
                    //Điều kiện trạng thái
                && (cboStatus.SelectedIndex > 0 ? p.Status == cboStatus.SelectedIndex - 1 : 1 == 1)
                ).OrderByDescending(p => p.CreatedDate).Take(size).ToList();
        }

        #endregion

        #region Hàm

        private void Insert()
        {
            try
            {
                var newItem = new Form.ucShippingRequestEdit() { Dock = DockStyle.Fill };
                var ui = Common.CreateForm(newItem, String.Empty, 510, 390);

                if (ui.ShowDialog() == DialogResult.OK)
                {
                    BindData();
                    Common.ShowSaveSuccess();
                }
            }
            catch (Exception ex)
            {
                Common.ShowErrorMess("Insert - " + ex.Message);
            }
        }

        private void Update()
        {
            try
            {
                if (sourceShippingRequest.Current == null)
                {
                    Common.ShowSelectionRequire();
                    return;
                }

                db = new UnigenDataContext();
                var selectedSR = sourceShippingRequest.Current as ShippingRequest;
                var newestSR = db.ShippingRequests.SingleOrDefault(p => p.RequestId == selectedSR.RequestId);

                var itemEdit = new Form.ucShippingRequestEdit() { Dock = DockStyle.Fill }.ForUpdate(newestSR);
                var ui = Common.CreateForm(itemEdit, String.Empty, 510, 390);

                if (ui.ShowDialog() == DialogResult.OK)
                {
                    BindData();
                    Common.ShowSaveSuccess();
                }
            }
            catch (Exception ex)
            {
                Common.ShowErrorMess("Update - " + ex.Message);
            }
        }

        private void Delete()
        {
            try
            {
                if (sourceShippingRequest.Current == null)
                {
                    Common.ShowSelectionRequire();
                    return;
                }

                db = new UnigenDataContext();
                var inputItem = (sourceShippingRequest.Current as ShippingRequest);
                if (inputItem.Status == 1)
                {
                    Common.ShowNoticeMess("Cannot remove the closed Shipping Request!");
                    return;
                } 
                if (inputItem.Active == true && Variables.UserRoleID == 1)
                {
                    Common.ShowNoticeMess("Cannot remove the confirmed Shipping Request!");
                    return;
                }

                if(Common.ShowQuestion("Remove this selected shipping request?") != DialogResult.OK)
                    return;

                var removeItem = db.ShippingRequests.SingleOrDefault(p => p.RequestId == inputItem.RequestId);
                //Xóa
                db.ShippingRequests.DeleteOnSubmit(removeItem);
                db.SubmitChanges();

                //Remove khỏi grid
                sourceShippingRequest.Remove(inputItem);
                Common.SetNo(grvShippingRequest);

                //Thông báo
                Common.ShowSaveSuccess();
            }
            catch (Exception ex)
            {
                Common.ShowErrorMess("Delete - " + ex.Message);
            }
        }

        private void ExportFile(List<ShippingRequest> data, string fileName, int exportType)
        {
            try
            {
                //datacontext
                db = new UnigenDataContext();

                //Tạo một đối tượng workbook
                var stream = new MemoryStream(global::UnigenReport.Properties.Resources.ShippingRequestReport);
                var workbook = new Workbook(stream);

                var cells = workbook.Worksheets[0].Cells;
                var rowIndex = 2;

                if(data.Count > 1)
                    cells.InsertRows(2, data.Count - 1);

                //Bắt đầu đổ dữ liệu
                for (var i = 0; i < data.Count; i++)
                {
                    var item = data[i];

                    //Cột STT
                    cells["A" + rowIndex].PutValue(i + 1);
                    //ID
                    cells["B" + rowIndex].PutValue(item.RequestId);
                    //State
                    cells["C" + rowIndex].PutValue(item.Status == 0 ? "OPEN" : "CLOSE");
                    //create date
                    cells["D" + rowIndex].PutValue(item.CreatedDate);
                    //WWO
                    cells["E" + rowIndex].PutValue(item.WorldOrder.WO);
                    //product
                    cells["F" + rowIndex].PutValue(item.WorldOrder.Product.ProductCode);
                    //name
                    cells["G" + rowIndex].PutValue(item.WorldOrder.Product.ProductName);
                    //add
                    cells["H" + rowIndex].PutValue(item.ShipAddress.Name + " (" + item.ShipAddress.Address + ")");
                    //quantity
                    cells["I" + rowIndex].PutValue(item.Quantity);
                    //active
                    cells["J" + rowIndex].PutValue(item.Active == true ? "CONFIRMED" : "WAITING");

                    rowIndex++;
                }

                try
                {
                    workbook.Save(fileName);

                    //Mở file Excel vừa lưu
                    if (exportType == 0) //Xuất excel
                    {
                        System.Diagnostics.Process.Start(fileName);
                    }
                    else //In
                    {
                        var config = new SystemConfig.UserConfig();
                        Common.PrintExcelAuto(fileName, config.PrintCopies);
                    }
                }
                catch (Exception ex)
                {
                    Common.ShowErrorMess("ExportFile - " + ex.Message);
                    return;
                }
            }
            catch (Exception ex)
            {
                Common.ShowErrorMess("ExportFile - " + ex.Message);
                return;
            }
        }

        private void SetImportState(bool isImport)
        {
            if (isImport)
            {
                cmbImport.Visibility = ElementVisibility.Visible;
                cmbMenu.Enabled = pnlSearch.Enabled = false;
                grvShippingRequest.CellDoubleClick -= grvShippingRequest_CellDoubleClick;
            }
            else
            {
                cmbImport.Visibility = ElementVisibility.Collapsed;
                cmbMenu.Enabled = pnlSearch.Enabled = true;
                grvShippingRequest.CellDoubleClick += grvShippingRequest_CellDoubleClick;
            }
        }

        #endregion
        
        #region Sự kiện

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Enter)
            {
                BindData();
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }

        private void btnInsert_Click(object sender, EventArgs e)
        {
            Insert();
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            Update();
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            Delete();
        }

        private void btnGetData_Click(object sender, EventArgs e)
        {
            BindData();
        }

        private void btnApprove_Click(object sender, EventArgs e)
        {
            if (sourceShippingRequest.Current == null)
            {
                Common.ShowSelectionRequire();
                return;
            }

            if (Common.ShowQuestion("Confirm this selected Shipping Request?") == DialogResult.OK)
            {
                db = new UnigenDataContext();
                var current = sourceShippingRequest.Current as ShippingRequest;
                var update = db.ShippingRequests.SingleOrDefault(p => p.RequestId == current.RequestId);
                if (update != null)
                {
                    update.Active = true;
                    db.SubmitChanges();

                    BindData();
                }
            }
        }
        
        private void btnCloseForm_Click(object sender, EventArgs e)
        {
            if (!isCallFromInvoice)
                (this.Parent as Telerik.WinControls.UI.RadPageViewPage).Dispose();
            else
            {
                refData.Clear();
                this.ParentForm.DialogResult = DialogResult.Cancel;
            }
        }

        private void btnSearch_Click(object sender, EventArgs e)
        {
            BindData();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            refData.Clear();
            foreach(var row in grvShippingRequest.Rows.Where(p=> Convert.ToBoolean(p.Cells["Selected"].Value ?? false)))
            {
                var addItem = row.DataBoundItem as ShippingRequest;
                refData.Add(addItem);
            }
            this.ParentForm.DialogResult = DialogResult.OK;
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            var source = GetData();
            if (source.Count == 0) return;

            //Xuat file
            var saveFileDialog = new SaveFileDialog
            {
                FileName = String.Format("ListShippingRequest{0}.xls", DateTime.Now.ToString("yyyyMMddHHmmss"))
            };

            if (saveFileDialog.ShowDialog() != DialogResult.OK)
            {
                return;
            }

            if (saveFileDialog.FileName.Equals(String.Empty))
            {
                return;
            }

            var fileName = saveFileDialog.FileName;
            ExportFile(source, fileName, 0);
        }

        private void btnPrint_Click(object sender, EventArgs e)
        {
            var source = GetData();
            if (source.Count == 0) return;

            var dir = "Temp";
            if (!System.IO.File.Exists(dir))
                System.IO.Directory.CreateDirectory(dir);
            var fileName = String.Format("ListShippingRequest{0}.xls", DateTime.Now.ToString("yyyyMMddHHmmss"));
            ExportFile(source, dir + "\\" + fileName, 1);
        }

        private void btnImport_Click(object sender, EventArgs e)
        {
            try
            {
                //Chon file
                var openFileDialog = new OpenFileDialog();

                if (openFileDialog.ShowDialog() != DialogResult.OK)
                {
                    return;
                }

                if (openFileDialog.FileName.Equals(String.Empty))
                {
                    return;
                }

                var fileName = openFileDialog.FileName;

                //Import
                var workbook = new Workbook(fileName);
                var cells = workbook.Worksheets[0].Cells;

                var lstImport = new List<ShippingRequest>();
                var success = true;
                var row = 2;
                var error = String.Empty;
                while (cells["B" + row].Value != null)
                {
                    var item = new ShippingRequest();
                    var wo = db.WorldOrders.SingleOrDefault(p => p.WO == (cells["B" + row].Value ?? "").ToString().Trim());
                    if (wo == null)
                    {
                        error = "WO " + (cells["B" + row].Value ?? "").ToString() + " (dòng " + row + ")  không tồn tại";
                        success = false;
                        break;
                    }
                    item.WorldOrder = wo;

                    var add = db.ShipAddresses.FirstOrDefault(p => p.ShipAddressId == Convert.ToInt32((cells["C" + row].Value ?? "").ToString()));
                    if (add == null)
                    {
                        error = "Địa chỉ " + (cells["G" + row].Value ?? "").ToString() + " (dòng " + row + ")  không tồn tại";
                        success = false;
                        break;
                    }
                    item.ShipAddress = add;

                    int quantity = 0;
                    int.TryParse((cells["D" + row].Value ?? "").ToString(), out quantity);
                    int totalQty = (int)(wo.Ordered - wo.Debit);
                    int requestedQty = Convert.ToInt32(db.ShippingRequests.Where(p => p.WOId == wo.WOId).Sum(p => p.Quantity) ?? 0);
                    int importedQty = lstImport.Where(p => p.WorldOrder == wo).Sum(p => p.Quantity ?? 0);
                    var maxQuantity = totalQty - requestedQty - importedQty;
                    if (maxQuantity < quantity)
                    {
                        error = "Số lượng hàng của WO " + wo.WO + " (dòng " + row + ")  vượt quá cho phép (" + maxQuantity + ")";
                        success = false;
                        break;
                    }
                    item.Quantity = quantity;

                    item.Status = 0;
                    item.CreatedDate = DateTime.Now;
                    item.Active = Variables.UserRoleID == 1 ? false : true;

                    //Add to list
                    lstImport.Add(item);

                    row++;
                }
                if (!success)
                {
                    Common.ShowErrorMess(error);
                }
                else
                {
                    SetImportState(true);
                    sourceShippingRequest.Clear();
                    sourceShippingRequest.DataSource = lstImport;
                    Common.SetNo(grvShippingRequest);
                }
            }
            catch (Exception ex)
            {
                Common.ShowErrorMess("btnImport_Click - " + ex.Message);
            }
        }

        private void btnExportTemp_Click(object sender, EventArgs e)
        {
            try
            {
                //Xuat file
                var saveFileDialog = new SaveFileDialog
                {
                    FileName = "ShippingRequestTemplate.xls"
                };

                if (saveFileDialog.ShowDialog() != DialogResult.OK)
                {
                    return;
                }

                if (saveFileDialog.FileName.Equals(String.Empty))
                {
                    return;
                }

                var fileName = saveFileDialog.FileName;

                //Mở file template cần đổ dữ liệu vào
                var stream = new MemoryStream(global::UnigenReport.Properties.Resources.ShippingRequestTemplate);
                //Tạo một đối tượng workbook
                var workbook = new Workbook(stream);

                db = new UnigenDataContext();
                //WO
                var cells = workbook.Worksheets[1].Cells;
                var wo = db.WorldOrders.Where(p => (p.Closed ?? false) == false).OrderByDescending(p => p.WO).ToList();
                var index = 2;
                foreach (var item in wo)
                {
                    cells["A" + index].Value = index - 1;
                    cells["B" + index].Value = item.WO;
                    cells["C" + index].Value = item.PO;
                    cells["D" + index].Value = item.SO;
                    cells["E" + index].Value = item.Product.ProductCode;
                    cells["F" + index].Value = item.Ordered;
                    cells["G" + index].Value = item.Shipped;
                    cells["H" + index].Value = item.Debit;
                    cells["I" + index].Value = item.Remained;

                    index++;
                }

                //add
                cells = workbook.Worksheets[2].Cells;
                var add = db.ShipAddresses.Where(p => p.Type == 1).OrderBy(p => p.ShipAddressId).ToList();
                index = 2;
                foreach (var item in add)
                {
                    cells["A" + index].Value = index - 1;
                    cells["B" + index].Value = item.ShipAddressId;
                    cells["C" + index].Value = item.Name;
                    cells["D" + index].Value = item.Address;
                    cells["E" + index].Value = item.Phone;
                    cells["F" + index].Value = item.Fax;

                    index++;
                }
                workbook.Save(fileName);

                //Mở file Excel vừa lưu
                System.Diagnostics.Process.Start(fileName);
            }
            catch (Exception ex)
            {
                Common.ShowErrorMess(ex.Message);
            }
        }

        private void btnSaveImport_Click(object sender, EventArgs e)
        {
            if (sourceShippingRequest.Count == 0)
            {
                Common.ShowNoticeMess("No data input!");
                SetImportState(false);
                BindData();
                return;
            }

            db = new UnigenDataContext();
            foreach (var item in (sourceShippingRequest.DataSource as List<ShippingRequest>))
                db.ShippingRequests.InsertOnSubmit(item.Clone());

            db.SubmitChanges();
            BindData();
            //menu
            SetImportState(false);
        }

        private void btnCancelImport_Click(object sender, EventArgs e)
        {
            BindData();
            //menu
            SetImportState(false);
        }
        
        private void grvShippingRequest_CellClick(object sender, GridViewCellEventArgs e)
        {
            if (e.RowIndex > -1 && e.Column.Name.Equals("Selected"))
                e.Row.Cells["Selected"].Value = !Convert.ToBoolean(e.Row.Cells["Selected"].Value ?? false);
        }

        private void grvShippingRequest_CellDoubleClick(object sender, GridViewCellEventArgs e)
        {
            Update();
        }

        private void chkCreated_ToggleStateChanged(object sender, StateChangedEventArgs args)
        {
            txtCreated.Enabled = chkCreated.Checked;
        }

        #endregion
    }
}
